package com.mxpio.erp.equipment.service.impl;

import com.mxpio.erp.common.enums.EquipmentEnums;
import com.mxpio.erp.common.enums.OrderStatusEnums;
import com.mxpio.erp.common.equipment.entity.EquipmentEqpBasics;
import com.mxpio.erp.common.equipment.entity.EquipmentEqpStatusChange;
import com.mxpio.erp.common.equipment.entity.EquipmentEqpStatusChangeLine;
import com.mxpio.erp.common.equipment.entity.EquipmentEqpStatusRecords;
import com.mxpio.erp.common.equipment.service.EquipmentEqpStatusChangeService;
import com.mxpioframework.common.exception.MBootException;
import com.mxpioframework.common.vo.Result;
import com.mxpioframework.jpa.JpaUtil;
import com.mxpioframework.security.util.SecurityUtils;
import com.mxpioframework.system.service.impl.BaseServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class EquipmentEqpStatusChangeServiceImpl extends BaseServiceImpl<EquipmentEqpStatusChange> implements EquipmentEqpStatusChangeService {

    @Override
    @Transactional
    public Result<EquipmentEqpStatusChange> updateCloseStatus(String bizNo, OrderStatusEnums.CloseStatus open) {
        EquipmentEqpStatusChange wo = this.getById(EquipmentEqpStatusChange.class,bizNo);
        if(wo==null) {
            return Result.error("申请单号未能查询到数据，请确认");
        }
        if(OrderStatusEnums.CloseStatus.CLOSED.equals(open) && wo.getCloseStatus().equals(OrderStatusEnums.CloseStatus.CLOSED.getStatusCode())){
            return Result.error("非打开状态不可关闭");
        }else if(OrderStatusEnums.CloseStatus.OPEN.equals(open) && wo.getCloseStatus().equals(OrderStatusEnums.CloseStatus.OPEN.getStatusCode())){
            return Result.error("非关闭状态不可打开");
        }
        wo.setCloseStatus(open.getStatusCode());
        this.update(wo);
        return Result.OK(wo);
    }

    @Override
    @Transactional
    public Result<EquipmentEqpStatusChange> updateBpmnStatus(String bizNo, OrderStatusEnums.BpmnStatus bpmnStatus) {
        EquipmentEqpStatusChange wo = this.getById(EquipmentEqpStatusChange.class,bizNo);
        if(wo==null) {
            return Result.error("申请单号未能查询到数据，请确认");
        }
        if(bpmnStatus.getStatusCode().equals(OrderStatusEnums.BpmnStatus.AUDITING.getStatusCode())&&!wo.getBpmnStatus().equals(OrderStatusEnums.BpmnStatus.CREATE.getStatusCode())){
            return Result.error("非开立状态不可提交");
        }
        if(bpmnStatus.getStatusCode().equals(OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode())&&!wo.getBpmnStatus().equals(OrderStatusEnums.BpmnStatus.AUDITING.getStatusCode())){
            return Result.error("非审核中状态不可审核");
        }
        if(bpmnStatus.getStatusCode().equals(OrderStatusEnums.BpmnStatus.CREATE.getStatusCode())&&
                !(wo.getBpmnStatus().equals(OrderStatusEnums.BpmnStatus.AUDITING.getStatusCode())||wo.getBpmnStatus().equals(OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode()))){
            return Result.error("非审核中、已审核状态不可弃审");
        }
        if (bpmnStatus.getStatusCode().equals(OrderStatusEnums.BpmnStatus.AUDITING.getStatusCode())&&!wo.getApplyType().equals(EquipmentEnums.EqpBasicsStatus.SCRAP.getCode())){
            Long count = JpaUtil.linq(EquipmentEqpStatusChangeLine.class).equal("bizNo", bizNo).equal("status", EquipmentEnums.EqpBasicsStatus.SCRAP.getCode()).count();
            if (count>0){
                return Result.error("申请明细中的数据存在报废状态的台账明细！");
            }
        }
        wo.setBpmnStatus(bpmnStatus.getStatusCode());
        wo.setReviewer(SecurityUtils.getLoginUsername());
        wo.setReviewTime(new Date());
        this.update(wo);
        return Result.OK(wo);
    }

    @Override
    @Transactional
    public Result<EquipmentEqpStatusChange> execute(String bizNo) {
        EquipmentEqpStatusChange wo = this.getById(EquipmentEqpStatusChange.class,bizNo);
        if(wo==null) {
            return Result.error("申请单号未能查询到数据，请确认");
        }
        if(!wo.getBpmnStatus().equals(OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode())){
            return Result.error("仅已审核状态可以执行！");
        }
        List<EquipmentEqpStatusChangeLine> lineList = JpaUtil.linq(EquipmentEqpStatusChangeLine.class).collect("basicsCode", EquipmentEqpBasics.class, "basicsCode").equal("bizNo", bizNo).list();
        if (lineList==null||lineList.isEmpty()){
            return Result.error("申请单明细为空！");
        }
        if (!wo.getApplyType().equals(EquipmentEnums.EqpBasicsStatus.SCRAP.getCode())){
            Set<String> eqpIdSet = lineList.stream().map(EquipmentEqpStatusChangeLine::getBasicsCode).collect(Collectors.toSet());
            Long count = JpaUtil.linq(EquipmentEqpBasics.class).in("basicsCode", eqpIdSet).equal("status", EquipmentEnums.EqpBasicsStatus.SCRAP.getCode()).count();
            if (count>0){
                return Result.error("申请单明细存在已报废状态设备台账，不能执行！");
            }
        }
        for (EquipmentEqpStatusChangeLine line:lineList){
            //添加设备状态记录
            EquipmentEqpStatusRecords records = new EquipmentEqpStatusRecords();
            records.setBasicsCode(line.getBasicsCode());
            records.setIsDel(0);
            records.setNowStatus(wo.getApplyType());
            EquipmentEqpBasics eqpBasics = line.getEqpBasics();
            if (eqpBasics==null){
                throw new MBootException("明细数据中关联设备台账为空！");
            }
            records.setBeforeStatus(eqpBasics.getStatus());
            eqpBasics.setStatus(wo.getApplyType());
            JpaUtil.save(eqpBasics);
            if (StringUtils.isBlank(line.getReason())){
                records.setReason(wo.getMemo());
            }else{
                records.setReason(line.getReason());
            }
            JpaUtil.save(records);
        }
        wo.setOrderStatus(OrderStatusEnums.OrderStatus.FINISHED.getStatusCode());//单据状态更新为已执行
        JpaUtil.update(wo);
        return Result.OK(wo);
    }
}
